package screen;

import java.io.IOException;
import java.io.InputStream;
import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

import keyboard.KeyCode;
import state.State;
import utils.Screen;
import book.Book;
import files.Files;

public class SplashScreen extends Canvas {

	private static final int NUM_FADE_STEP = 8;

	private Graphics g;
	private Book book;
	private Image image;
	private boolean isSplash;
	private int fadeStep = 0;
	private int numRepaint = 0;
	private int displayStep = 0;
	private boolean isAlreadySetup = false;
	private boolean isCasualSplash = false;

	public SplashScreen(Book aBook) {
		book = aBook;
		try {
			FileConnection fconn = (FileConnection) Connector.open(Files
					.getBookIllustrationFile());
			InputStream in = fconn.openInputStream();
			image = Image.createImage(in);
			in.close();
			fconn.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	protected void paint(Graphics someg) {
		g = someg;

		paintPauseMessage();

		if (isCasualSplash) {
			paintCasualSplash();
		} else {
			paintFadingSplash();
		}

	}

	private void paintPauseMessage() {
		if (Book.getState().equals(State.IN_PAUSE)) {
			String text = "Pause";
			g.setColor(Colors.GREY);
			showMessage(text);
		}
	}

	private void paintFadingSplash() {
		numRepaint++;
		if (!isAlreadySetup) {
			eraseSlate();
			isAlreadySetup = true;
		}

		if (displayStep == 0) {
			if ((isSplash) && (fadeStep < NUM_FADE_STEP)) {
				drawFadingGrayScaleImage();
				fadeStep++;
			}
		} else if (displayStep == 2) {
			if ((isSplash) && (fadeStep > 0)) {
				fadeStep--;
				drawFadingGrayScaleImage();
			}
		}
	}

	private void paintCasualSplash() {
		g.drawImage(image, Screen.SCREEN_WIDTH / 2, Screen.BLACK_TOP_HEIGHT
				+ Screen.SIDE_MARGIN, Graphics.HCENTER | Graphics.TOP);
	}

	private void eraseSlate() {
		int previousColor = g.getColor();
		g.setColor(Colors.BLACK);
		g.fillRect(0, 0, Screen.SCREEN_WIDTH, Screen.SCREEN_HEIGHT);
		g.setColor(Colors.WHITE);
		// g.fillRoundRect(0, BLACK_TOP_HEIGHT, SCREEN_WIDTH, SIDE_MARGIN * 3
		// + g.getFont().getHeight() * 6, 10, 10);
		g.fillRect(0, Screen.BLACK_TOP_HEIGHT, Screen.SCREEN_WIDTH,
				Screen.SIDE_MARGIN * 3 + g.getFont().getHeight() * 6);
		g.setColor(previousColor);
	}

	public void doCasualSplash() {
		isCasualSplash = true;
		isSplash = false;
		repaint();
	}

	public void doFadingSplash() {
		isCasualSplash = false;
		isSplash = true;
		repaint();
		new Timer().schedule(new TimerTask() {

			public void run() {
				book.startReading();
			}
		}, 3000);

		for (int i = 0; i < NUM_FADE_STEP; i++) {
			new Timer().schedule(new TimerTask() {
				public void run() {
					repaint();
				}
			}, 1200 * i / (NUM_FADE_STEP - 1));
		}

		new Timer().schedule(new TimerTask() {
			public void run() {
				displayStep = 1;
			}
		}, 1200);

		new Timer().schedule(new TimerTask() {
			public void run() {
				displayStep = 2;
			}
		}, 1800);

		for (int i = 0; i < NUM_FADE_STEP; i++) {
			new Timer().schedule(new TimerTask() {
				public void run() {
					repaint();
				}
			}, 2400 + 600 * i / (NUM_FADE_STEP - 1));
		}
	}

	public void keyPressed(int keyCode) {
		if (keyCode == KeyCode.BAS) {
			book.startReading();
		}
	}

	private void drawFadingGrayScaleImage() {
		// work out how many pixels, and create array
		int width = image.getWidth();
		int height = image.getHeight();
		int[] pixels = new int[width * height];
		// get the pixel data
		image.getRGB(pixels, 0, width, 0, 0, width, height);
		// convert to grey scale
		for (int i = 0; i < pixels.length; i++) {
			// get one pixel
			int argb = pixels[i];
			// separate colour components
			int alpha = (argb >> 24) & 0xff;
			int initRed = ((argb >> 16) & 0xff);
			int initGreen = (argb >> 8) & 0xff;
			int initBlue = argb & 0xff;
			// construct grey value
			int red = (initRed - 255) / (NUM_FADE_STEP - 1) * fadeStep + 255;
			int green = (initGreen - 255) / (NUM_FADE_STEP - 1) * fadeStep
					+ 255;
			int blue = (initBlue - 255) / (NUM_FADE_STEP - 1) * fadeStep + 255;

			int grey = (((red * 30) / 100) + ((green * 59) / 100) + ((blue * 11) / 100)) & 0xff;
			// grey = grey * 3 / 4 + 255 / 4; // Lighter

			// reconstruct pixel with grey value - keep original alpha
			// argb = (alpha << 24) | (grey << 16) | (grey << 8) | grey;
			argb = (alpha << 24) | (red << 16) | (green << 8) | blue;
			// put back in the pixel array
			pixels[i] = argb;
		}
		// create and return a new Image
		Image greyImage = Image.createRGBImage(pixels, width, height, true);
		g.drawImage(greyImage, Screen.SCREEN_WIDTH / 2, Screen.BLACK_TOP_HEIGHT
				+ Screen.SIDE_MARGIN, Graphics.HCENTER | Graphics.TOP);
	}

	private void showMessage(String text) {
		g.setColor(Colors.GREY);
		g.drawString(text, Screen.SCREEN_WIDTH / 2,
				g.getFont().getHeight() / 2, Graphics.TOP | Graphics.HCENTER);
	}
}
